import React, { useState, useRef, useEffect, useCallback } from 'react';
import { Button, Icon, message, Spin, Tabs } from 'antd';
import ProTable, { TableDropdown } from '@ant-design/pro-table';
import { Form } from '@ant-design/compatible';
import { useRequest, useInViewport } from '@umijs/hooks';
import TreeControlled from '@/components/blocks/TreeControlled';
import styles from './index.less';
import Detail from './components/Detail';
import Edit from './components/Edit';
import { getModuleTree, getResources, batchDisabled, deleteResource } from './service';
import Add from './components/Add';
import AuthComponent from '@/components/Authorized/AuthComponent';

const TableList = () => {
  const [detailVisible, setDetailVisible] = useState(false);
  const [editVisible, setEditVisible] = useState(false);
  const [addVisible, setAddVisible] = useState(false);
  const [detailItem, setDetailItem] = useState(false);
  const [editItem, setEditItem] = useState(false);
  const searchRef = useRef();
  const [selectedKeys, setSelectedKeys] = useState([]);
  // 用于重置缓存页面的tab选中状态
  const inViewPort = useInViewport(() => document.querySelector('#pageViewId'));

  // 计算高度
  const [height, controlH] = useState(300);
  const [isCollapse, controlC] = useState(true);
  useEffect(() => {
    if (isCollapse) {
      controlH(document.body.clientHeight - 360);
    } else {
      controlH(document.body.clientHeight - 526.5);
    }
  }, [isCollapse])

  const [treeItem, setTreeItem] = useState({});
  const { loading, data, run } = useRequest(getModuleTree, {
    onSuccess: ([root]) => {
      setTreeItem(root);
      if (root.key) {
        setSelectedKeys([root.key]);
      } else {
        setSelectedKeys(['0-0']);
      }
    },
  });

  const reloadTable = useCallback(function reloadData() {
    if (searchRef.current) {
      searchRef.current.click();
    }
  }, []);

  const reloadData = useCallback(
    function reloadData() {
      reloadTable();
      run();
    },
    [run, reloadTable],
  );

  const [inited, setInited] = useState(false);
  useEffect(() => {
    if (!inited) {
      setInited(true);
    } else {
      reloadTable();
    }
  }, [inited, treeItem, reloadTable]);

  const options = {
    changeState: {
      func: ({ status, id }) =>
        batchDisabled({ status: !status, id: Array.isArray(id) ? id : [id] }),
      callback: (_, row) => {
        message.success(row.status ? '禁用成功!' : '启用成功!');
        reloadData();
      },
    },
    remove: {
      func: ({ id }) => deleteResource({ id: Array.isArray(id) ? id : [id] }),
      callback: (_, row) => {
        message.success('删除成功');
        reloadData();
      },
    },
    edit: {
      func: row => {
        setEditItem(row);
        setEditVisible(true);
        return Promise.resolve(true);
      },
    },
    add: {
      func: row => {
        setAddVisible(true);
        return Promise.resolve(true);
      },
    },
  };

  const optionHandle = function optionHandle(key, ...rest) {
    const { func, callback = () => { } } = options[key];
    func(...rest).then(res => callback(res, ...rest));
  };

  const columns = [
    {
      title: '模块名称',
      dataIndex: 'name',
    },
    {
      title: '操作',
      valueType: 'option',
      dataIndex: 'id',
      width: 100,
      hideInTable: !(
        AuthComponent.getAuth('user.menu.view') ||
        AuthComponent.getAuth('user.menu.edit') ||
        AuthComponent.getAuth('user.menu.enable_disable') ||
        AuthComponent.getAuth('user.menu.remove')
      ),
      render: (text, row) => [
        <AuthComponent authCode="user.menu.view">
          <Button
            onClick={() => {
              setDetailItem(row);
              setDetailVisible(true);
            }}
            type="link"
            style={{ padding: 0 }}
          >
            查看
          </Button>
        </AuthComponent>,
        <TableDropdown
          onSelect={key => optionHandle(key, row)}
          menus={[]
            .concat(AuthComponent.getAuth('user.role.edit') ? [{ key: 'edit', name: '编辑' }] : [])
            .concat(
              AuthComponent.getAuth('user.role.enable_disable')
                ? [
                  {
                    key: 'changeState',
                    name: row.status ? '禁用' : '启用',
                  },
                ]
                : [],
            )
            .concat(
              AuthComponent.getAuth('user.role.remove') ? [{ key: 'remove', name: '删除' }] : [],
            )}
        />,
      ],
    },
    {
      title: '模块类型',
      dataIndex: 'types',
      valueEnum: {
        '0': '组件',
        '1': '页面',
        '2': '菜单',
      },
      hideInSearch: true,
    },
    {
      title: '状态',
      dataIndex: 'status',
      valueEnum: {
        true: { text: '启用', status: 'Success' },
        false: { text: '禁用', status: 'Default' },
      },
      hideInSearch: true,
    },
    {
      title: 'URL',
      dataIndex: 'resourceUrl',
      hideInSearch: true,
    },
    {
      title: 'ICON',
      dataIndex: 'icon',
      hideInSearch: true,
    },
    {
      title: '组件ID',
      dataIndex: 'componentsId',
      hideInSearch: true,
    },
    {
      title: '端口',
      dataIndex: 'portName',
      hideInSearch: true,
    },
  ];

  const onSelect = function onSelect(keys, { selected, node }) {
    if (selected) {
      setTreeItem({ ...node.props, key: node.props.eventKey });
      setSelectedKeys(keys);
    }
  };

  const onDetailClose = function onDetailClose() {
    setDetailVisible(false);
    setDetailItem(false);
  };

  const onEditClose = function onEditClose() {
    setEditVisible(false);
    setAddVisible(false);
    setEditItem(false);
  };

  return (
    <section id="pageViewId" className={styles.wrapper}>
      <Tabs className={styles.treeWrapper}>
        <Tabs.TabPane tab="应用模块树" key="1">
          <Spin spinning={loading}>
            <TreeControlled
              className={styles.tree}
              selectable
              data={data}
              selectedKeys={selectedKeys}
              setSelectedKeys={onSelect}
            />
          </Spin>
        </Tabs.TabPane>
      </Tabs>
      <div className={`${styles.table} rest-pro-table-form-compact`}>
        <ProTable
          size='small'
          options={{density: false,fullScreen:true, reload:false, setting:true}}
          className={`${styles.messageTable} rest-pro-table-form-compact ${isCollapse ? '' : 'collapse'}`}
          scroll={{ x: 1200, y: height }}
          pagination={{
            showSizeChanger: true,
            showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 项`
          }}
          rowSelection={{}}
          headerTitle={
            <span style={{ paddingRight: 10, fontWeight: 'bold', color: '#000' }}>
              {treeItem && treeItem.title}
            </span>
          }
          search={{
            searchText: (
              <span ref={searchRef} href>
                查询
              </span>
            ),
            onCollapse: val => {
              controlC(val);
            }
          }}
          rowKey="id"
          toolBarRender={(_, { selectedRowKeys }) =>
            [
              <AuthComponent authCode="user.menu.add">
                <Button type="primary" onClick={() => optionHandle('add')}>
                  <Icon type="add" />
                  新增
                </Button>
              </AuthComponent>,
            ].concat(
              selectedRowKeys && selectedRowKeys.length
                ? [
                  <AuthComponent authCode="user.menu.remove">
                    <Button onClick={() => optionHandle('remove', { id: selectedRowKeys })}>
                      删除
                      </Button>
                  </AuthComponent>,
                  <AuthComponent authCode="user.menu.enable_disable">
                    <Button
                      onClick={() =>
                        optionHandle('changeState', {
                          id: selectedRowKeys,
                          status: false,
                        })
                      }
                    >
                      启用
                      </Button>
                  </AuthComponent>,
                  <AuthComponent authCode="user.menu.enable_disable">
                    <Button
                      onClick={() =>
                        optionHandle('changeState', {
                          id: selectedRowKeys,
                          status: true,
                        })
                      }
                    >
                      禁用
                      </Button>
                  </AuthComponent>,
                ]
                : [],
            )
          }
          request={params =>
            getResources({
              ...params,
              key:
                selectedKeys.length > 0 ? (selectedKeys[0] === '0-0' ? '' : selectedKeys[0]) : '',
            })
          }
          columns={columns}
        />
      </div>
      {detailItem && (
        <Detail visible={detailVisible} onClose={onDetailClose} current={detailItem} />
      )}
      {editItem && (
        <Edit
          visible={editVisible}
          data={{ ...editItem, selectedKeys }}
          onSuccess={reloadData}
          onClose={onEditClose}
        />
      )}
      {addVisible && (
        <Add
          visible={addVisible}
          data={{ treeItem, selectedKeys }}
          onSuccess={reloadData}
          onClose={onEditClose}
        />
      )}
    </section>
  );
};

export default Form.create()(TableList);
